package zhihuilan.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.ha3engine.vector.Client;
import com.aliyun.ha3engine.vector.models.Config;
import com.aliyun.ha3engine.vector.models.PushDocumentsRequest;
import com.aliyun.ha3engine.vector.models.PushDocumentsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.ha3engine.vector.models.*;
import com.aliyun.teautil.Common;
import org.springframework.util.ObjectUtils;
import sun.misc.BASE64Encoder;
import zhihuilan.dto.MySearchDto;
import zhihuilan.params.query.MySearchQueryParam;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AliPushSearchDoc {
    /**
     * 问天引擎client
     */


    public Client clientInit() throws Exception {
        Config config = new Config();
        // 实例名称，可在实例详情页左上角查看，例:ha-cn-i7*****605
        config.setInstanceId("ha-cn-jte49bevd04");
        // 用户名，可在实例详情页>API入口 查看
        config.setAccessUserName("root");
        // 密码，可在实例详情页>API入口 修改
        config.setAccessPassWord("Zhl13329618858@");
        // API域名，可在实例详情页>API入口 查看
        config.setEndpoint("ha-cn-jte49bevd04.public.ha.aliyuncs.com");
        return new Client(config);
    }

    public void addShop(MySearchDto mySearch) throws Exception {
        // 文档推送的表名称，是实例id与表名的拼接，中间用下划线连接
        String tableName = "ha-cn-jte49bevd04_zhl_shop";
        // 文档推送的文档主键字段.
        String pkField = "id";
        try {
            // 文档推送外层结构, 可添加对文档操作的结构体. 结构内支持一个或多个文档操作内容.
            ArrayList<Map<String, ?>> documents = new ArrayList<>();
            // 添加文档
            Map<String, Object> add2Document = new HashMap<>();
            Map<String, Object> add2DocumentFields = new HashMap<>();
            // 插入文档内容信息, keyValue 成对匹配.
            // field_pk 字段需与 pkField 字段配置一致.
            add2DocumentFields.put("id", mySearch.getPid());
            add2DocumentFields.put("source_text",mySearch.getName());
            add2DocumentFields.put("lat", mySearch.getLat());
            add2DocumentFields.put("lng", mySearch.getLng());
            add2DocumentFields.put("title", mySearch.getName());
            add2DocumentFields.put("staff_id", mySearch.getStaffId());
            add2DocumentFields.put("logo",imageUrlToBase64(mySearch.getLogo()));
            add2DocumentFields.put("img",mySearch.getLogo());
            add2DocumentFields.put("intro", mySearch.getContent());
            add2DocumentFields.put("title_txt", mySearch.getName());
            add2DocumentFields.put("intro_txt", mySearch.getContent());
            add2DocumentFields.put("districtid",mySearch.getDistrictid());
            add2DocumentFields.put("address1",mySearch.getAddress1());
            add2DocumentFields.put("region",mySearch.getRegion());
            add2DocumentFields.put("address2",mySearch.getAddress2());
            // 将文档内容添如 add2Document 结构.
            add2Document.put("fields", add2DocumentFields);
            // 新增对应的文档命令: add
            add2Document.put("cmd", "add");
            documents.add(add2Document);
            // 推送数据
            PushDocumentsRequest request = new PushDocumentsRequest();
            // 推送数据时，默认校验是否存在主键字段。如需关闭校验，请设置请求头 X-Opensearch-Validate-Data: false
//            request.headers = new HashMap<>();
//            request.headers.put("X-Opensearch-Validate-Data", "false");
            request.setBody(documents);
            // System.out.println(clientInit()._endpoint.toString());
            PushDocumentsResponse response = clientInit().pushDocuments(tableName, pkField, request);
            String responseBody = response.getBody();

            System.out.println("result：" + responseBody);
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(Common.toJSONString(exceptionData));
        }
    }

    public void addGoods(MySearchDto mySearch) throws Exception {
        // 文档推送的表名称，是实例id与表名的拼接，中间用下划线连接
        String tableName = "ha-cn-jte49bevd04_zhl_search";
        // 文档推送的文档主键字段.
        String pkField = "id";
        try {
            // 文档推送外层结构, 可添加对文档操作的结构体. 结构内支持一个或多个文档操作内容.
            ArrayList<Map<String, ?>> documents = new ArrayList<>();
            // 添加文档
            Map<String, Object> add2Document = new HashMap<>();
            Map<String, Object> add2DocumentFields = new HashMap<>();
            // 插入文档内容信息, keyValue 成对匹配.
            // field_pk 字段需与 pkField 字段配置一致.
            add2DocumentFields.put("id", mySearch.getPid());
            add2DocumentFields.put("source_image",imageUrlToBase64(mySearch.getImg()!=null?mySearch.getImg().split(",")[0]:null));
            add2DocumentFields.put("lat", mySearch.getLat());
            add2DocumentFields.put("lng", mySearch.getLng());
            add2DocumentFields.put("video", mySearch.getVideo());
            add2DocumentFields.put("staff_id", mySearch.getStaffId());
            add2DocumentFields.put("logo", mySearch.getLogo());
            add2DocumentFields.put("fid", mySearch.getFid());
            add2DocumentFields.put("pid", mySearch.getPid());
            add2DocumentFields.put("img", mySearch.getImg());
            add2DocumentFields.put("name", mySearch.getName());
            add2DocumentFields.put("content", mySearch.getContent());
            add2DocumentFields.put("name_txt", mySearch.getName());
            add2DocumentFields.put("content_txt", mySearch.getContent());
            add2DocumentFields.put("districtid",mySearch.getDistrictid());
            add2DocumentFields.put("staff_title",mySearch.getStaffTitle());
            add2DocumentFields.put("staff_logo",mySearch.getStaffLogo());
            // 将文档内容添如 add2Document 结构.
            add2Document.put("fields", add2DocumentFields);
            // 新增对应的文档命令: add
            add2Document.put("cmd", "add");
            documents.add(add2Document);
            // 推送数据
            PushDocumentsRequest request = new PushDocumentsRequest();
            // 推送数据时，默认校验是否存在主键字段。如需关闭校验，请设置请求头 X-Opensearch-Validate-Data: false
//            request.headers = new HashMap<>();
//            request.headers.put("X-Opensearch-Validate-Data", "false");
            request.setBody(documents);
           // System.out.println(clientInit()._endpoint.toString());
            PushDocumentsResponse response = clientInit().pushDocuments(tableName, pkField, request);
            String responseBody = response.getBody();

           System.out.println("result：" + responseBody);
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(Common.toJSONString(exceptionData));
        }
    }


    public void addCircle(MySearchDto mySearch) throws Exception {
        // 文档推送的表名称，是实例id与表名的拼接，中间用下划线连接
        String tableName = "ha-cn-jte49bevd04_zhl_circle";
        // 文档推送的文档主键字段.
        String pkField = "id";
        try {
            // 文档推送外层结构, 可添加对文档操作的结构体. 结构内支持一个或多个文档操作内容.
            ArrayList<Map<String, ?>> documents = new ArrayList<>();
            // 添加文档
            Map<String, Object> add2Document = new HashMap<>();
            Map<String, Object> add2DocumentFields = new HashMap<>();
            // 插入文档内容信息, keyValue 成对匹配.
            // field_pk 字段需与 pkField 字段配置一致.
            add2DocumentFields.put("id", mySearch.getPid());
            add2DocumentFields.put("source_img",imageUrlToBase64(mySearch.getImg()!=null?mySearch.getImg().split(",")[0]:null));
            add2DocumentFields.put("source_text",mySearch.getContent());
            add2DocumentFields.put("lat", mySearch.getLat());
            add2DocumentFields.put("lng", mySearch.getLng());
            add2DocumentFields.put("video", mySearch.getVideo());
            add2DocumentFields.put("staff_id", mySearch.getStaffId());
            add2DocumentFields.put("logo", mySearch.getLogo());
            add2DocumentFields.put("fid", mySearch.getFid());
            add2DocumentFields.put("pid", mySearch.getPid());
            add2DocumentFields.put("image", mySearch.getImg());
            add2DocumentFields.put("title", mySearch.getName());
            add2DocumentFields.put("content", mySearch.getContent());
            add2DocumentFields.put("region", mySearch.getRegion()==null?mySearch.getStaffRegion():mySearch.getRegion());
            add2DocumentFields.put("address", mySearch.getAddress());
            add2DocumentFields.put("address1", mySearch.getStaffAddress2());
            add2DocumentFields.put("districtid",mySearch.getDistrictid());
            add2DocumentFields.put("staff_title",mySearch.getStaffTitle());
            add2DocumentFields.put("staff_logo",mySearch.getStaffLogo()!=null?mySearch.getStaffLogo():mySearch.getStaffHeadimgurl());
            add2DocumentFields.put("staff_address",mySearch.getStaffAddress1());

            // 将文档内容添如 add2Document 结构.
            add2Document.put("fields", add2DocumentFields);
            // 新增对应的文档命令: add
            add2Document.put("cmd", "add");
            documents.add(add2Document);
            // 推送数据
            PushDocumentsRequest request = new PushDocumentsRequest();
            // 推送数据时，默认校验是否存在主键字段。如需关闭校验，请设置请求头 X-Opensearch-Validate-Data: false
//            request.headers = new HashMap<>();
//            request.headers.put("X-Opensearch-Validate-Data", "false");
            request.setBody(documents);
            // System.out.println(clientInit()._endpoint.toString());
            PushDocumentsResponse response = clientInit().pushDocuments(tableName, pkField, request);
            String responseBody = response.getBody();

            System.out.println("result：" + responseBody);
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(Common.toJSONString(exceptionData));
        }
    }


    AliyunUtils aliyunUtils = new AliyunUtils();

        public Map queryImageByGoods(MySearchQueryParam mySearchQueryParam) throws Exception {
            try {
                Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());
                String filter = "";
                if(mySearchQueryParam.getType()==0){
                    filter = " fid = 0 ";
                }else {
                    filter = " fid > 0 ";
                    filter += " AND distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";
                }
                if(!ObjectUtils.isEmpty(mySearchQueryParam.getDistrictid())&&mySearchQueryParam.getDistrictid()>0){
                    if(mySearchQueryParam.getDistrictid()<100){
                        filter += " AND districtid > "+mySearchQueryParam.getDistrictid()*10000+" AND districtid < "+(mySearchQueryParam.getDistrictid()*10000+10000);
                    }else if(mySearchQueryParam.getDistrictid()>999&&mySearchQueryParam.getDistrictid()<100000){
                        filter += " AND districtid > "+mySearchQueryParam.getDistrictid()*100+" AND districtid < "+(mySearchQueryParam.getDistrictid()*100+10000);
                    }
                    else if(mySearchQueryParam.getDistrictid()>100000){
                        filter += " AND districtid = "+mySearchQueryParam.getDistrictid();
                    }
                }
                QueryRequest request = new QueryRequest();
                request.setTableName("zhl_search"); // 必填项, 查询的表名
                request.setIndexName("imageVector");
                request.setContent( imageUrlToBase64(mySearchQueryParam.getKeyword())); // 必填项,查询的内容
                request.setModal("image"); // 必填项,用于向量化查询词
                request.setTopK(top); // 非必填项, 返回个数
                request.setSearchParams("{\\\"qc.searcher.scan_ratio\\\":0.01,\\\"crop\\\":true}");
                request.setFilter(filter);
                request.setOutputFields(Arrays.asList("pid","name","content","fid","staff_id","img","logo","lat","lng","districtid","staff_title","staff_logo")); // 需要返回值的字段列表
                request.setOrder("ASC");
                SearchResponse searchResponse = clientInit().inferenceQuery(request);
                SearchResponse searchResponse1 = clientInit().stats("zhl_search");
                JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
                Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");
                System.out.println(jsonObject);
                List<MySearchDto> list = new ArrayList<>();
                if(!ObjectUtils.isEmpty(jsonObject)) {
                    for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                        JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                        MySearchDto mySearchDto = new MySearchDto();
                        mySearchDto.setId(jsonObject1.getInteger("pid"));
                        mySearchDto.setImg(jsonObject1.getString("img").split(",")[0]);
                        mySearchDto.setLogo(jsonObject1.getString("img").split(",")[0]);
                        mySearchDto.setFid(jsonObject1.getInteger("fid"));
                        mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                        mySearchDto.setLng(jsonObject1.getString("lng"));
                        mySearchDto.setLat(jsonObject1.getString("lat"));
                        mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                        mySearchDto.setName(jsonObject1.getString("name"));
                        mySearchDto.setContent(jsonObject1.getString("content"));
                        mySearchDto.setPid(jsonObject1.getInteger("pid"));
                        mySearchDto.setStaffTitle(jsonObject1.getString("staff_title"));
                        mySearchDto.setStaffHeadimgurl(jsonObject1.getString("staff_logo"));
                        if(!ObjectUtils.isEmpty(mySearchQueryParam.getLat())){
                            mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                        }
                        System.out.println(jsonObject1);
                        list.add(mySearchDto);
                    }
                }
                Map map = new HashMap();
                map.put("data",list);
                map.put("total",total);
                return map;
            } catch (TeaException e) {
                System.out.println(e.getCode());
                System.out.println(e.getMessage());
                Map<String, Object> exceptionData = e.getData();
                System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
            }
            return  null;
        }
    public Map  queryTextByCircle(MySearchQueryParam mySearchQueryParam) throws Exception {
        try {
            Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());

            String filter = "";

           // filter = " distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";

            if(!ObjectUtils.isEmpty(mySearchQueryParam.getDistrictid())&&mySearchQueryParam.getDistrictid()>0){
                if(mySearchQueryParam.getDistrictid()<100){
                    filter += "  districtid > "+mySearchQueryParam.getDistrictid()*10000+" AND districtid < "+(mySearchQueryParam.getDistrictid()*10000+10000);
                }else if(mySearchQueryParam.getDistrictid()>999&&mySearchQueryParam.getDistrictid()<100000){
                    filter += "  districtid > "+mySearchQueryParam.getDistrictid()*100+" AND districtid < "+(mySearchQueryParam.getDistrictid()*100+10000);
                }
                else if(mySearchQueryParam.getDistrictid()>100000){
                    filter += "  districtid = "+mySearchQueryParam.getDistrictid();
                }
            }
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.setTableName("zhl_circle"); //查询的表名

            QueryRequest request = new QueryRequest();
            request.setIndexName("vector");
            List<Float>  vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77","ops-text-embedding-001");
            request.setVector(vector);
            request.setFilter(filter);
            request.setTopK(300);
            request.setSearchParams("{\\\"hnsw.searcher.scan_ratio\\\":0.01}");
            searchRequest.setKnn(request);
            TextQuery textQuery = new TextQuery();
            textQuery.setQueryString("content_txt:'"+mySearchQueryParam.getKeyword()+"' OR title_txt:'"+mySearchQueryParam.getKeyword()+"'");
            textQuery.setFilter(filter);
            searchRequest.setText(textQuery);
            searchRequest.setSize(300);
            searchRequest.setOutputFields(Arrays.asList("id","title","content","region","image","lat","lng","districtid","staff_id","address1","staff_title","staff_logo")); // 需要返回值的字段列表
            searchRequest.setOrder("DESC");

//            MultiQueryRequest multiQueryRequest = new MultiQueryRequest();
//
//            multiQueryRequest.setTableName("zhl_shop"); //查询的表名
//            multiQueryRequest.setTopK(top); // 最终返回的结果个数
//            multiQueryRequest.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
//            multiQueryRequest.setOrder("DESC");
//            List<Float> vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77");
//            QueryRequest queryRequest = new QueryRequest();
//            queryRequest.setIndexName("intro_vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest.setFilter(filter);
//            QueryRequest queryRequest1 = new QueryRequest();
//            queryRequest1.setIndexName("vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest1.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest1.setFilter(filter);
//            multiQueryRequest.setQueries(Arrays.asList(queryRequest,queryRequest1));
//            multiQueryRequest.setFilter(filter);

            SearchResponse searchResponse = clientInit().search(searchRequest);
            SearchResponse searchResponse1 = clientInit().stats("zhl_circle");
            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");

            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");
            System.out.println(jsonObject);
            List<MySearchDto> list = new ArrayList<>();
            if(!ObjectUtils.isEmpty(jsonObject)) {
                for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                    if(jsonObject.size()>i) {
                        JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                        MySearchDto mySearchDto = new MySearchDto();
                        mySearchDto.setId(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setPid(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setImg(jsonObject1.getString("image"));
                        mySearchDto.setLogo(jsonObject1.getString("logo"));
                        mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                        mySearchDto.setLng(jsonObject1.getString("lng"));
                        mySearchDto.setLat(jsonObject1.getString("lat"));
                        mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                        mySearchDto.setName(jsonObject1.getString("title"));
                        mySearchDto.setContent(jsonObject1.getString("content"));
                        mySearchDto.setRegion(jsonObject1.getString("region"));
                        mySearchDto.setAddress1(jsonObject1.getString("address1"));
                        mySearchDto.setStaffTitle(jsonObject1.getString("staff_title"));
                        mySearchDto.setStaffLogo(jsonObject1.getString("staff_logo"));
                        mySearchDto.setStaffHeadimgurl(jsonObject1.getString("logo"));
                       // mySearchDto.setType(2);
//                        mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                        System.out.println(jsonObject1);
                        list.add(mySearchDto);
                    }
                }
            }
            //  list.sort((o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance()));
            Map map = new HashMap();
            map.put("data",list);
            map.put("total",total);
            return map;
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
        }
        return null;
    }

    public Map  queryTextByGoods(MySearchQueryParam mySearchQueryParam) throws Exception {
        try {
            Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());
            String filter = "";
            if(mySearchQueryParam.getType()==0){
                filter = " fid = 0 ";
            }else {
                filter = " fid > 0 ";
                filter += " AND distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";
            }

            if(!ObjectUtils.isEmpty(mySearchQueryParam.getDistrictid())&&mySearchQueryParam.getDistrictid()>0){
                if(mySearchQueryParam.getDistrictid()<100){
                    filter += " AND districtid > "+mySearchQueryParam.getDistrictid()*10000+" AND districtid < "+(mySearchQueryParam.getDistrictid()*10000+10000);
                }else if(mySearchQueryParam.getDistrictid()>999&&mySearchQueryParam.getDistrictid()<100000){
                    filter += " AND districtid > "+mySearchQueryParam.getDistrictid()*100+" AND districtid < "+(mySearchQueryParam.getDistrictid()*100+10000);
                }
                else if(mySearchQueryParam.getDistrictid()>100000){
                    filter += " and districtid = "+mySearchQueryParam.getDistrictid();
                }
            }

            SearchRequest searchRequest = new SearchRequest();
            searchRequest.setTableName("zhl_search"); //查询的表名

            QueryRequest request = new QueryRequest();
            request.setIndexName("nameVector");
            List<Float>  vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77","ops-text-embedding-001");
            request.setVector(vector);
            request.setFilter(filter);
            request.setTopK(1000);
            request.setSearchParams("{\\\"hnsw.searcher.scan_ratio\\\":0.01}");
            searchRequest.setKnn(request);
            TextQuery textQuery = new TextQuery();
            textQuery.setQueryString("name_txt:'"+mySearchQueryParam.getKeyword()+"' OR content_txt:'"+mySearchQueryParam.getKeyword()+"'");
            textQuery.setFilter(filter);
            searchRequest.setText(textQuery);
            searchRequest.setSize(1000);
            searchRequest.setOutputFields(Arrays.asList("pid","name","content","fid","staff_id","img","logo","lat","lng","districtid","staff_title","staff_logo")); // 需要返回值的字段列表
            searchRequest.setOrder("DESC");


//            MultiQueryRequest multiQueryRequest = new MultiQueryRequest();
//
//            multiQueryRequest.setTableName("zhl_search"); //查询的表名
//            multiQueryRequest.setTopK(top); // 最终返回的结果个数
//            multiQueryRequest.setOutputFields(Arrays.asList("pid","name","content","fid","staff_id","img","logo","lat","lng","districtid","staff_title","staff_logo")); /// 需要返回值的字段列表
//            multiQueryRequest.setOrder("DESC");
//            List<Float> vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77","ops-text-embedding-001");
//            System.out.println(vector);
//            QueryRequest queryRequest = new QueryRequest();
//            queryRequest.setIndexName("contentVector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest.setFilter(filter);
//            QueryRequest queryRequest1 = new QueryRequest();
//            queryRequest1.setIndexName("nameVector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest1.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest1.setFilter(filter);
//            multiQueryRequest.setQueries(Arrays.asList(queryRequest,queryRequest1));
//            multiQueryRequest.setFilter(filter);

            SearchResponse searchResponse = clientInit().search(searchRequest);
            SearchResponse searchResponse1 = clientInit().stats("zhl_search");

//            SearchResponse searchResponse = clientInit().search(searchRequest);
//            SearchResponse searchResponse1 = clientInit().stats("zhl_shop");
            System.out.println(searchResponse);
            System.out.println(searchResponse.body);
            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");

            List<MySearchDto> list = new ArrayList<>();
            if(!ObjectUtils.isEmpty(jsonObject)) {
                for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                    JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                    MySearchDto mySearchDto = new MySearchDto();
                    mySearchDto.setId(jsonObject1.getInteger("pid"));
                    mySearchDto.setImg(jsonObject1.getString("img").split(",")[0]);
                    mySearchDto.setLogo(jsonObject1.getString("img").split(",")[0]);
                    mySearchDto.setFid(jsonObject1.getInteger("fid"));
                    mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                    mySearchDto.setLng(jsonObject1.getString("lng"));
                    mySearchDto.setLat(jsonObject1.getString("lat"));
                    mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                    mySearchDto.setName(jsonObject1.getString("name"));
                    mySearchDto.setContent(jsonObject1.getString("content"));
                    mySearchDto.setPid(jsonObject1.getInteger("pid"));
                    mySearchDto.setStaffTitle(jsonObject1.getString("staff_title"));
                    mySearchDto.setStaffHeadimgurl(jsonObject1.getString("staff_logo"));
                    if(!ObjectUtils.isEmpty(mySearchQueryParam.getLat())){
                        mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                    }
                     System.out.println(jsonObject1);
                    list.add(mySearchDto);
                }
            }
            Map map = new HashMap();
            map.put("data",list);
            map.put("total",total);
            return map;
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
        }
        return null;
    }

    public Map  queryTextByShops(MySearchQueryParam mySearchQueryParam) throws Exception {
        try {
            Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());

            String filter = "";

           filter = " distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";

            SearchRequest searchRequest = new SearchRequest();
            searchRequest.setTableName("zhl_shop"); //查询的表名

            QueryRequest request = new QueryRequest();
            request.setIndexName("intro_vector");
            List<Float>  vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77","ops-text-embedding-001");
            request.setVector(vector);
            request.setFilter(filter);
            request.setTopK(300);
            request.setSearchParams("{\\\"hnsw.searcher.scan_ratio\\\":0.01}");
            searchRequest.setKnn(request);
            TextQuery textQuery = new TextQuery();
            textQuery.setQueryString("title_txt:'"+mySearchQueryParam.getKeyword()+"' OR intro_txt:'"+mySearchQueryParam.getKeyword()+"'");
            textQuery.setFilter(filter);
            searchRequest.setText(textQuery);
            searchRequest.setSize(300);
            searchRequest.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
            searchRequest.setOrder("DESC");

//            MultiQueryRequest multiQueryRequest = new MultiQueryRequest();
//
//            multiQueryRequest.setTableName("zhl_shop"); //查询的表名
//            multiQueryRequest.setTopK(top); // 最终返回的结果个数
//            multiQueryRequest.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
//            multiQueryRequest.setOrder("DESC");
//            List<Float> vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77");
//            QueryRequest queryRequest = new QueryRequest();
//            queryRequest.setIndexName("intro_vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest.setFilter(filter);
//            QueryRequest queryRequest1 = new QueryRequest();
//            queryRequest1.setIndexName("vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest1.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest1.setFilter(filter);
//            multiQueryRequest.setQueries(Arrays.asList(queryRequest,queryRequest1));
//            multiQueryRequest.setFilter(filter);

            SearchResponse searchResponse = clientInit().search(searchRequest);
            SearchResponse searchResponse1 = clientInit().stats("zhl_shop");
            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");

            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");
            System.out.println(jsonObject);
            List<MySearchDto> list = new ArrayList<>();
            if(!ObjectUtils.isEmpty(jsonObject)) {

                for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                    if(jsonObject.size()>i) {
                        JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                        MySearchDto mySearchDto = new MySearchDto();
                        mySearchDto.setId(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setPid(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setImg(jsonObject1.getString("img"));
                        mySearchDto.setLogo(jsonObject1.getString("img"));
                        mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                        mySearchDto.setLng(jsonObject1.getString("lng"));
                        mySearchDto.setLat(jsonObject1.getString("lat"));
                        mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                        mySearchDto.setName(jsonObject1.getString("title"));
                        mySearchDto.setContent(jsonObject1.getString("intro"));
                        mySearchDto.setRegion(jsonObject1.getString("region"));
                        mySearchDto.setAddress1(jsonObject1.getString("address1"));
                        mySearchDto.setType(2);
                        mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                        System.out.println(jsonObject1);
                        list.add(mySearchDto);
                    }
                }
            }
          //  list.sort((o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance()));
            Map map = new HashMap();
            map.put("data",list);
            map.put("total",total);
            return map;
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
        }
        return null;
    }

    public Map  queryImageByShops(MySearchQueryParam mySearchQueryParam) throws Exception {
        try {
            Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());

            String filter = "";

            filter = " distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";

            QueryRequest request = new QueryRequest();
            request.setTableName("zhl_shop"); // 必填项, 查询的表名
            request.setContent( imageUrlToBase64(mySearchQueryParam.getKeyword())); // 必填项,查询的内容
            request.setModal("image"); // 必填项,用于向量化查询词
            request.setTopK(300); // 非必填项, 返回个数
            request.setSearchParams("{\\\"qc.searcher.scan_ratio\\\":0.01}");
            request.setFilter(filter);
            request.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
            request.setOrder("ASC");
            SearchResponse searchResponse = clientInit().inferenceQuery(request);
            SearchResponse searchResponse1 = clientInit().stats("zhl_search");
            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");


//            MultiQueryRequest multiQueryRequest = new MultiQueryRequest();
//
//            multiQueryRequest.setTableName("zhl_shop"); //查询的表名
//            multiQueryRequest.setTopK(top); // 最终返回的结果个数
//            multiQueryRequest.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
//            multiQueryRequest.setOrder("DESC");
//            List<Float> vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77");
//            QueryRequest queryRequest = new QueryRequest();
//            queryRequest.setIndexName("intro_vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest.setFilter(filter);
//            QueryRequest queryRequest1 = new QueryRequest();
//            queryRequest1.setIndexName("vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest1.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest1.setFilter(filter);
//            multiQueryRequest.setQueries(Arrays.asList(queryRequest,queryRequest1));
//            multiQueryRequest.setFilter(filter);

//            SearchResponse searchResponse = clientInit().search(searchRequest);
//            SearchResponse searchResponse1 = clientInit().stats("zhl_shop");
//            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
//
//            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");
            System.out.println(jsonObject);
            List<MySearchDto> list = new ArrayList<>();
            if(!ObjectUtils.isEmpty(jsonObject)) {

                for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                    if(jsonObject.size()>i) {
                        JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                        MySearchDto mySearchDto = new MySearchDto();
                        mySearchDto.setId(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setPid(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setImg(jsonObject1.getString("img"));
                        mySearchDto.setLogo(jsonObject1.getString("img"));
                        mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                        mySearchDto.setLng(jsonObject1.getString("lng"));
                        mySearchDto.setLat(jsonObject1.getString("lat"));
                        mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                        mySearchDto.setName(jsonObject1.getString("title"));
                        mySearchDto.setContent(jsonObject1.getString("intro"));
                        mySearchDto.setRegion(jsonObject1.getString("region"));
                        mySearchDto.setAddress1(jsonObject1.getString("address1"));
                        mySearchDto.setType(2);
                        mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                        System.out.println(jsonObject1);
                        list.add(mySearchDto);
                    }
                }
            }
            //  list.sort((o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance()));
            Map map = new HashMap();
            map.put("data",list);
            map.put("total",total);
            return map;
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
        }
        return null;
    }


    public Map  queryImageByCircle(MySearchQueryParam mySearchQueryParam) throws Exception {
        try {
            Integer top =(int)(mySearchQueryParam.getPage() * mySearchQueryParam.getPageSize());

            String filter = "";

            filter = " distance(lng,lat,'"+mySearchQueryParam.getLng()+"','"+mySearchQueryParam.getLat()+"') < 100 ";

            QueryRequest request = new QueryRequest();
            request.setTableName("zhl_shop"); // 必填项, 查询的表名
            request.setContent( imageUrlToBase64(mySearchQueryParam.getKeyword())); // 必填项,查询的内容
            request.setModal("image"); // 必填项,用于向量化查询词
            request.setTopK(300); // 非必填项, 返回个数
            request.setSearchParams("{\\\"qc.searcher.scan_ratio\\\":0.01}");
            request.setFilter(filter);
            request.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
            request.setOrder("ASC");
            SearchResponse searchResponse = clientInit().inferenceQuery(request);
            SearchResponse searchResponse1 = clientInit().stats("zhl_search");
            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");


//            MultiQueryRequest multiQueryRequest = new MultiQueryRequest();
//
//            multiQueryRequest.setTableName("zhl_shop"); //查询的表名
//            multiQueryRequest.setTopK(top); // 最终返回的结果个数
//            multiQueryRequest.setOutputFields(Arrays.asList("id","title","intro","region","img","lat","lng","districtid","staff_id","address1")); // 需要返回值的字段列表
//            multiQueryRequest.setOrder("DESC");
//            List<Float> vector = aliyunUtils.TextEmbedding(mySearchQueryParam.getKeyword(),"OS-05phw15oyli52t77");
//            QueryRequest queryRequest = new QueryRequest();
//            queryRequest.setIndexName("intro_vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest.setFilter(filter);
//            QueryRequest queryRequest1 = new QueryRequest();
//            queryRequest1.setIndexName("vector"); // 查询的索引名 必须在SearchRequest中指定或者在每个Query中指定
//            queryRequest1.setVector( vector); // 查询的向量数据，多个向量可以平铺开
//            queryRequest1.setFilter(filter);
//            multiQueryRequest.setQueries(Arrays.asList(queryRequest,queryRequest1));
//            multiQueryRequest.setFilter(filter);

//            SearchResponse searchResponse = clientInit().search(searchRequest);
//            SearchResponse searchResponse1 = clientInit().stats("zhl_shop");
//            JSONArray jsonObject = JSONObject.parseObject(searchResponse.body).getJSONArray("result");
//
//            Integer total = JSONObject.parseObject(searchResponse1.body).getJSONObject("result").getInteger("totalDocCount");
            System.out.println(jsonObject);
            List<MySearchDto> list = new ArrayList<>();
            if(!ObjectUtils.isEmpty(jsonObject)) {

                for (Long i = (top - mySearchQueryParam.getPageSize()); i < top; i++) {
                    if(jsonObject.size()>i) {
                        JSONObject jsonObject1 = jsonObject.getJSONObject(i.intValue()).getJSONObject("fields");
                        MySearchDto mySearchDto = new MySearchDto();
                        mySearchDto.setId(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setPid(jsonObject.getJSONObject(i.intValue()).getInteger("id"));
                        mySearchDto.setImg(jsonObject1.getString("img"));
                        mySearchDto.setLogo(jsonObject1.getString("img"));
                        mySearchDto.setDistrictid(jsonObject1.getString("districtid"));
                        mySearchDto.setLng(jsonObject1.getString("lng"));
                        mySearchDto.setLat(jsonObject1.getString("lat"));
                        mySearchDto.setStaffId(jsonObject1.getInteger("staff_id"));
                        mySearchDto.setName(jsonObject1.getString("title"));
                        mySearchDto.setContent(jsonObject1.getString("intro"));
                        mySearchDto.setRegion(jsonObject1.getString("region"));
                        mySearchDto.setAddress1(jsonObject1.getString("address1"));
                        mySearchDto.setType(2);
                        mySearchDto.setDistance(ToolsUtils.calculateDistance(jsonObject1.getDouble("lat"), jsonObject1.getDouble("lng"), Double.parseDouble(mySearchQueryParam.getLat()), Double.parseDouble(mySearchQueryParam.getLng())));
                        System.out.println(jsonObject1);
                        list.add(mySearchDto);
                    }
                }
            }
            //  list.sort((o1, o2) -> Double.compare(o1.getDistance(), o2.getDistance()));
            Map map = new HashMap();
            map.put("data",list);
            map.put("total",total);
            return map;
        } catch (TeaException e) {
            System.out.println(e.getCode());
            System.out.println(e.getMessage());
            Map<String, Object> exceptionData = e.getData();
            System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
        }
        return null;
    }

        public void delete(Integer type,Integer id) throws Exception {
            // 文档推送的表名称，是实例id与表名的拼接，中间用下划线连接
            String tableName = "ha-cn-jte49bevd04_zhl_search";
            if(type.equals(1)){
                tableName = "ha-cn-jte49bevd04_zhl_shop";
            }else if(type.equals(2)){
                tableName = "ha-cn-jte49bevd04_zhl_circle";
            }
            // 文档推送的文档主键字段.
            String pkField = "id";

            try {
                // 文档推送外层结构, 可添加对文档操作的结构体. 结构内支持一个或多个文档操作内容.
                ArrayList<Map<String, ?>> documents = new ArrayList<>();

                // 删除文档
                Map<String, Object> delete2Document = new HashMap<>();
                Map<String, Object> delete2DocumentFields = new HashMap<>();

                // 插入文档内容信息, keyValue 成对匹配.
                // field_pk 字段需与 pkField 字段配置一致.
                delete2DocumentFields.put("id", id);

                // 将文档内容添如 delete2Document 结构.
                delete2Document.put("fields", delete2DocumentFields);
                // 删除对应的文档命令: delete
                delete2Document.put("cmd", "delete");
                documents.add(delete2Document);

                // 推送数据
                PushDocumentsRequest request = new PushDocumentsRequest();
                request.setBody(documents);
                PushDocumentsResponse response = clientInit().pushDocuments(tableName, pkField, request);
                String responseBody = response.getBody();

                System.out.println("result：" + responseBody);

            } catch (TeaException e) {
                System.out.println(e.getCode());
                System.out.println(e.getMessage());
                Map<String, Object> exceptionData = e.getData();
                System.out.println(com.aliyun.teautil.Common.toJSONString(exceptionData));
            }
        }

    public static String imageUrlToBase64(String imgUrl) {
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;

        try {
            url = new URL(imgUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();

            is = httpUrl.getInputStream();
            outStream = new ByteArrayOutputStream();

            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            //使用输入流从buffer里把数据读取出来
            while( (len = is.read(buffer)) != -1 ){
                //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                outStream.write(buffer, 0, len);
            }

            // 对字节数组Base64编码
            return encode(outStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(is != null) {
                    is.close();
                }
                if(outStream != null) {
                    outStream.close();
                }
                if(httpUrl != null) {
                    httpUrl.disconnect();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     * 图片转字符串
     * @param image 图片Buffer
     * @return Base64编码
     */
    public static String encode(byte[] image){
        BASE64Encoder decoder = new BASE64Encoder();
        return replaceEnter(decoder.encode(image));
    }
    /**
     * 字符替换
     * @param str 字符串
     * @return 替换后的字符串
     */
    public static String replaceEnter(String str){
        String reg ="[\n-\r]";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }



}
